﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using AsyncCamera.Camera.Pelco;

namespace Incendios0_1.Camera.Pelco
{
    class CameraProtocol
    {
        private static byte syn = 255;
        public static byte BOL = syn;

        public static byte checksuma(float modx)
        {
            return Convert.ToByte(Math.Truncate(modx + 0.5));
        }

        /// <summary>
        /// Con este método la cámara se mueve hacia arriba según la velocidad del scroll (la cual la mueve el usuario).
        /// Requiere de entrada la dirección de la camara y la velocidad.
        /// </summary>
        /// <param name="cameraID"></param>es la dirección de la cámara
        /// <param name="scrolltilt"></param> este parametro es el que se obtiene de la barra de velocidad
        /// <returns></returns>
        public static byte[] MoveUp(PelcoCamera camera)
        {
            float vel = Convert.ToSingle(camera.cameraData.VSpeed / 100.0 * 63.0);
            byte veltilt = Convert.ToByte(vel);
            byte direccion = Convert.ToByte(camera.cameraData.HWControlAddress);
            byte tiltup = 8;
            float x = tiltup + Convert.ToByte(camera.cameraData.HWControlAddress) + vel;
            float modx = x % 256;
            byte checksum = checksuma(modx);
            byte[] buffer = new byte[] { syn, direccion, 0, tiltup, 0, veltilt, checksum };
            return buffer;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="cameraID"></param>
        /// <param name="scrolltilt"></param>
        /// <returns></returns>
        public static byte[] MoveDown(PelcoCamera camera)
        {
            float vel = Convert.ToSingle(camera.cameraData.VSpeed / 100.0 * 63.0);
            byte veltilt = Convert.ToByte(vel);
            byte direccion = Convert.ToByte(camera.cameraData.HWControlAddress);
            byte tiltdown = 16;
            float x = tiltdown + Convert.ToByte(camera.cameraData.HWControlAddress) + vel;
            float modx = x % 256;
            byte checksum = checksuma(modx);
            byte[] buffer = new byte[] { syn, direccion, 0, tiltdown, 0, veltilt, checksum };
            return buffer;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="cameraID"></param>
        /// <param name="scrollpan"></param>
        /// <returns></returns>
        public static byte[] MoveRight(PelcoCamera camera)
        {
            byte direccion = Convert.ToByte(camera.cameraData.HWControlAddress);
                byte panright = 2;
                byte[] buffer;
                if (camera.cameraData.turbo)
                    buffer = TurboMoveRight(direccion, panright);
                else
                {
                    float vel = Convert.ToSingle(camera.cameraData.HSpeed / 100.0 * 63.0);
                    byte velpan = Convert.ToByte(vel);
                    float x = panright + Convert.ToByte(camera.cameraData.HWControlAddress) +vel;
                    float modx = x % 256;
                    byte checksum = checksuma(modx);
                    buffer = new byte[] { syn, direccion, 0, panright, velpan, 0, checksum };
                }
                return buffer;

        }

        public static byte[] TurboMoveRight(byte cameraID,byte panright)
        {
            int x = panright + cameraID + 64;
            float modx = x % 256;
            byte checksum = checksuma(modx);
            byte[] buffer = new byte[] { syn, cameraID, 0, panright, 64, 0, checksum };
            return buffer;
        }


        public static byte[] MoveLeft(PelcoCamera camera)
        {
            byte panleft = 4;
            byte direccion = Convert.ToByte(camera.cameraData.HWControlAddress);
            byte[] buffer;
            if (camera.cameraData.turbo)
                buffer = TurboMoveLeft(direccion, panleft);
            
            else
            {
                float vel = Convert.ToSingle(camera.cameraData.HSpeed / 100.0 * 63.0);
                byte velpan = Convert.ToByte(vel);
                float x = panleft + Convert.ToByte(camera.cameraData.HWControlAddress) + vel;
                float modx = x % 256;
                byte checksum = checksuma(modx);
                buffer = new byte[] { syn, direccion, 0, panleft, velpan, 0, checksum };
            }
            return buffer;

        }

        public static byte[] TurboMoveLeft(byte cameraID, byte panleft)
        {
            float x = panleft + cameraID + 64;
            float modx = x % 256;
            byte checksum = checksuma(modx);
            byte[] buffer = new byte[] { syn, cameraID, 0, panleft, 64, 0, checksum };
            return buffer;
        }

        public static byte[] ZoomIn(PelcoCamera camera)
        {
            byte direccion = Convert.ToByte(camera.cameraData.HWControlAddress);
            byte zoomin = 32;
            int x = zoomin + Convert.ToByte(camera.cameraData.HWControlAddress);
            byte checksum = Convert.ToByte(x % 256);
            byte[] buffer = new byte[] { syn, direccion, 0, zoomin, 0, 0, checksum };
            return buffer;
        }

        public static byte[] ZoomOut(PelcoCamera camera)
        {
            byte direccion = Convert.ToByte(camera.cameraData.HWControlAddress);
            byte zoomout = 64;
            int x = zoomout + Convert.ToByte(camera.cameraData.HWControlAddress);
            byte checksum = Convert.ToByte(x % 256);
            byte[] buffer = new byte[] { syn, direccion, 0, zoomout, 0, 0, checksum };
            return buffer;
        }

        public static byte[] FocusNear(PelcoCamera camera)
        {
            byte direccion = Convert.ToByte(camera.cameraData.HWControlAddress);
            byte fnear = 1;
            int x = fnear + Convert.ToByte(camera.cameraData.HWControlAddress);
            byte checksum = Convert.ToByte(x % 256);
            byte[] buffer = new byte[] { syn, direccion, fnear, 0, 0, 0, checksum };
            return buffer;
        }

        public static byte[] FocusFar(PelcoCamera camera)
        {
            byte direccion = Convert.ToByte(camera.cameraData.HWControlAddress);
            byte ffar = 128;
            int x = ffar + Convert.ToByte(camera.cameraData.HWControlAddress);
            byte checksum = Convert.ToByte(x % 256);
            byte[] buffer = new byte[] { syn, direccion, 0, ffar, 0, 0, checksum };
            return buffer;

        }

        public static byte[] OpenIris(PelcoCamera camera)
        {
            byte direccion = Convert.ToByte(camera.cameraData.HWControlAddress);
            byte irisopen = 2;
            int x = irisopen + Convert.ToByte(camera.cameraData.HWControlAddress);
            byte checksum = Convert.ToByte(x % 256);
            byte[] buffer = new byte[] { syn, direccion, irisopen, 0, 0, 0, checksum };//Se crea el buffer para el envio de la trama segun se necesite.

            return buffer;

        }

        public static byte[] CloseIris(PelcoCamera camera)
        {
            byte direccion = Convert.ToByte(camera.cameraData.HWControlAddress);
            byte irisclose = 4;
            int x = irisclose + Convert.ToByte(camera.cameraData.HWControlAddress);
            byte checksum = Convert.ToByte(x % 256);
            byte[] buffer = new byte[] { syn, direccion, irisclose, 0, 0, 0, checksum };
            return buffer;
        }

        public static byte[] Stop(PelcoCamera camera)
        {
            byte checksum = Convert.ToByte(camera.cameraData.HWControlAddress);
            byte[] buffer = new byte[] { syn, checksum, 0, 0, 0, 0, checksum };
            return buffer;
        }


        public static byte[] Wipe(PelcoCamera camera)
        {
            byte wiper = 9;
            byte aux = 1;
            byte com = 1;
            byte add = Convert.ToByte(camera.cameraData.HWControlAddress);
            byte check = Convert.ToByte(wiper + aux + com + add);
            byte[] buffer = new byte[] { syn, add, com, wiper, 0, aux, check };
            return buffer;
        }

        public static byte[] CallPreset(PelcoCamera camera)
        {
            byte preset = Convert.ToByte(camera.cameraData.Preset);
            byte add = Convert.ToByte(camera.cameraData.HWControlAddress);
            byte go = 7;
            byte check = Convert.ToByte(preset + add + go);
            byte[] buffer = new byte[] { syn, add, 0, go, 0, preset, check };
            return buffer;
        }

        public static byte[] SetPreset(PelcoCamera camera)
        {
            byte preset = Convert.ToByte(camera.cameraData.Preset);
            byte add = Convert.ToByte(camera.cameraData.HWControlAddress);
            byte go = 3;
            byte check = Convert.ToByte(preset + add + go);
            byte[] buffer = new byte[] { syn, add, 0, go, 0, preset, check };
            return buffer;
        }

        public static byte[] Menu(PelcoCamera camera)
        {
            byte menu = 95;
            byte add = Convert.ToByte(camera.cameraData.HWControlAddress);
            byte go = 3;
            byte check = Convert.ToByte(menu + add + go);
            byte[] buffer = new byte[] { syn, add, 0, go, 0, menu, check };
            return buffer;
        }

        public static byte[] ClearPreset(PelcoCamera camera)
        {
            byte preset = Convert.ToByte(camera.cameraData.Preset);
            byte add = Convert.ToByte(camera.cameraData.HWControlAddress);
            byte go = 5;
            byte check = Convert.ToByte(preset + add + go);
            byte[] buffer = new byte[] { syn, add, 0, go, 0, preset, check };
            return buffer;
        }

        public static byte[] querypan(PelcoCamera camera)
        {
            byte preset = 81;
            byte add = Convert.ToByte(camera.cameraData.HWControlAddress);
            decimal checksum = Convert.ToDecimal(preset) + Convert.ToDecimal(add);
            byte check = Convert.ToByte(checksum);
            byte[] bufferquerypan = new byte[] { syn, add, 0, preset, 0, 0, check };
            return bufferquerypan;
        }

        public static decimal readCoord(byte[] buffer1)
        {
            int entero = Convert.ToInt32(buffer1[11]);
            int dec = Convert.ToInt32(buffer1[12]);
            string hex1 = entero.ToString("X");
            string hex2 = dec.ToString("X");
            string total = hex1 + hex2;
            int enteroagain = (int.Parse(total, System.Globalization.NumberStyles.HexNumber));
            decimal angulo1 = Convert.ToDecimal(enteroagain);
            decimal angulo = angulo1 / 100;
            return angulo;
        }

        public static byte[] querytilt(PelcoCamera camera)
        {
            byte preset = 83;
            byte add = Convert.ToByte(camera.cameraData.HWControlAddress);
            decimal checksum = Convert.ToDecimal(preset) + Convert.ToDecimal(add);
            byte check = Convert.ToByte(checksum);
            byte[] bufferquerytilt = new byte[] { syn, add, 0, preset, 0, 0, check };
            return bufferquerytilt;
        }
    }
}
